package com.lam.common.utils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 字符串工具类
 * 
 * @author lam
 */
public class StringUtils extends org.apache.commons.lang3.StringUtils {

	private static final Logger logger = LoggerFactory.getLogger(StringUtils.class);

	/** 空字符串 */
	private static final String NULLSTR = "";

	/** 下划线 */
	private static final char SEPARATOR = '_';

	public static String toString(Object obj){
		return toString(obj, null);
	}
	
	public static String toString(Object o, String nullDefault) {
        return (o != null) ? o.toString() : nullDefault;
    }
	
	/**
	 * 获取参数不为空值
	 * 
	 * @param value defaultValue 要判断的value
	 * @return value 返回值
	 */
	public static <T> T nvl(T value, T defaultValue) {
		return value != null ? value : defaultValue;
	}

	/**
	 * * 判断一个字符串是否为空串
	 * 
	 * @param str String
	 * @return true：为空 false：非空
	 */
	public static boolean isEmpty(String str) {
		return str == null || str.isEmpty();
	}

	/**
	 * * 判断一个字符串是否为非空串
	 * 
	 * @param str String
	 * @return true：非空串 false：空串
	 */
	public static boolean isNotEmpty(String str) {
		return !isEmpty(str);
	}

	/**
	 * 去空格
	 */
	public static String trim(String str) {
		return (str == null ? "" : str.trim());
	}

	/**
	 * 截取字符串
	 * 
	 * @param str   字符串
	 * @param start 开始
	 * @return 结果
	 */
	public static String substring(final String str, int start) {
		if (str == null) {
			return NULLSTR;
		}

		if (start < 0) {
			start = str.length() + start;
		}

		if (start < 0) {
			start = 0;
		}
		if (start > str.length()) {
			return NULLSTR;
		}

		return str.substring(start);
	}

	/**
	 * 截取字符串
	 * 
	 * @param str   字符串
	 * @param start 开始
	 * @param end   结束
	 * @return 结果
	 */
	public static String substring(final String str, int start, int end) {
		if (str == null) {
			return NULLSTR;
		}

		if (end < 0) {
			end = str.length() + end;
		}
		if (start < 0) {
			start = str.length() + start;
		}

		if (end > str.length()) {
			return str;
		}

		if (start > end) {
			return NULLSTR;
		}

		if (start < 0) {
			start = 0;
		}
		if (end < 0) {
			end = 0;
		}

		return str.substring(start, end);
	}

	/**
	 * 字符串转set
	 * 
	 * @param str 字符串
	 * @param sep 分隔符
	 * @return set集合
	 */
	public static final Set<String> str2Set(String str, String sep) {
		return new HashSet<>(str2List(str, sep, true, false));
	}

	/**
	 * 字符串转list
	 * 
	 * @param str         字符串
	 * @param sep         分隔符
	 * @param filterBlank 过滤纯空白
	 * @param trim        去掉首尾空白
	 * @return list集合
	 */
	public static final List<String> str2List(String str, String sep, boolean filterBlank, boolean trim) {
		List<String> list = new ArrayList<>();
		if (StringUtils.isEmpty(str)) {
			return list;
		}

		// 过滤空白字符串
		if (filterBlank && StringUtils.isBlank(str)) {
			return list;
		}
		String[] split = str.split(sep);
		for (String string : split) {
			if (filterBlank && StringUtils.isBlank(string)) {
				continue;
			}
			if (trim) {
				string = string.trim();
			}
			list.add(string);
		}

		return list;
	}

	/**
	 * 下划线转驼峰命名
	 */
	public static String toUnderScoreCase(String str) {
		if (isBlank(str)) {
			return str;
		}
		
		StringBuilder sb = new StringBuilder();
		// 前置字符是否大写
		boolean preCharIsUpperCase = true;
		// 当前字符是否大写
		boolean curreCharIsUpperCase = true;
		// 下一字符是否大写
		boolean nexteCharIsUpperCase = true;
		for (int i = 0; i < str.length(); i++) {
			char c = str.charAt(i);
			if (i > 0) {
				preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1));
			} else {
				preCharIsUpperCase = false;
			}

			curreCharIsUpperCase = Character.isUpperCase(c);

			if (i < (str.length() - 1)) {
				nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1));
			}

			if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase) {
				sb.append(SEPARATOR);
			} else if ((i != 0 && !preCharIsUpperCase) && curreCharIsUpperCase) {
				sb.append(SEPARATOR);
			}
			sb.append(Character.toLowerCase(c));
		}

		return sb.toString();
	}

	/**
	 * 是否包含字符串
	 * 
	 * @param str  验证字符串
	 * @param strs 字符串组
	 * @return 包含返回true
	 */
	public static boolean inStringIgnoreCase(String str, String... strs) {
		if (str != null && strs != null) {
			for (String s : strs) {
				if (str.equalsIgnoreCase(trim(s))) {
					return true;
				}
			}
		}
		return false;
	}

//	/**
//	 * 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空，则返回空字符串。
//	 * 例如：HELLO_WORLD->HelloWorld
//	 * 
//	 * @param name 转换前的下划线大写方式命名的字符串
//	 * @return 转换后的驼峰式命名的字符串
//	 */
//	public static String convertToCamelCase(String name) {
//		
//		// 快速检查
//		if (isBlank(name)) {
//			return "";
//		} 
//		
//		if (!name.contains("_")) {
//			// 不含下划线，仅将首字母大写
//			return name.substring(0, 1).toUpperCase() + name.substring(1);
//		}
//		
//		StringBuilder result = new StringBuilder();
//		// 用下划线将原始字符串分割
//		String[] camels = name.split("_");
//		for (String camel : camels) {
//			// 跳过原始字符串中开头、结尾的下换线或双重下划线
//			if (camel.isEmpty()) {
//				continue;
//			}
//			// 首字母大写
//			result.append(camel.substring(0, 1).toUpperCase());
//			result.append(camel.substring(1).toLowerCase());
//		}
//		return result.toString();
//	}

	/**
	 * 将字符串首字母大写
	 * @param s
	 * @return
	 */
	public static String upperCaseFirst(String s) {
		if (isBlank(s)) {
			return s;
		}
		if(s.length()==1) {
			return s.toUpperCase();
		}
		return s.substring(0, 1).toUpperCase() + s.substring(1);
	}
	
	/**
	 * 下划线转驼峰，同时首字母大写， 例如：user_name->UserName
	 */
	public static String toCamelCaseWithUpFirst(String s) {
		return upperCaseFirst(toCamelCase(s));
	}
	
	/**
	 * 驼峰式命名法 例如：user_name->userName
	 */
	public static String toCamelCase(String s) {
		
		if (isBlank(s) || !s.contains("_")) {
			return s;
		}
		
		s = s.toLowerCase();
		StringBuilder sb = new StringBuilder();
		boolean upperCase = false;
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);

			if (c == SEPARATOR) {
				upperCase = true;
			} else if (upperCase) {
				sb.append(Character.toUpperCase(c));
				upperCase = false;
			} else {
				sb.append(c);
			}
		}
		return sb.toString();
	}
	
	/**
	 * 将驼峰命名转化成下划线
	 * @param para
	 * @return
	 */
	public static String camelToUnderline(String s){
		if (isBlank(s)) {
			return s;
		}
		
        if(s.length()<3){
        	return s.toLowerCase(); 
        }
        
        StringBuilder sb = new StringBuilder(s);
        int temp=0;//定位
        //从第三个字符开始 避免命名不规范 
        for(int i=2;i<s.length();i++){
            if(Character.isUpperCase(s.charAt(i))){
                sb.insert(i+temp, "_");
                temp+=1;
            }
        }
        return sb.toString().toLowerCase(); 
	}

	/**
	 * 将集合转换为字符串，使用英文逗号作为分隔符 例如：[str1,str2,str3...]=>"str1,str2,str3..."
	 *
	 * @param colle
	 * @return
	 * @date 2016年9月5日
	 * @author lam
	 */
	public static String list2Str(Collection<String> colle) {
		return list2Str(colle, null);
	}

	/**
	 * 将集合转换为字符串，根据给定分隔符 例如：用逗号分隔，[str1,str2,str3...]=>"str1,str2,str3..."
	 *
	 * @param colle
	 * @param separator
	 * @return
	 * @date 2016年9月5日
	 * @author lam
	 */
	public static String list2Str(Collection<String> colle, String separator) {
		if (colle == null) {
			return null;
		}
		if (colle.isEmpty()) {
			return "";
		}
		if (separator == null) {
			separator = ",";
		}
		StringBuilder s = new StringBuilder();
		Iterator<String> it = colle.iterator();
		if (it.hasNext()) {
			s.append(it.next());
		}
		while (it.hasNext()) {
			s.append(separator).append(it.next());
		}
		return s.toString();
	}

	/**
	 * 将字符串转换为List，使用英文逗号作为分隔符 例如："str1,str2,str3..."=>[str1,str2,str3...]
	 *
	 * @param str
	 * @return
	 * @date 2016年9月5日
	 * @author lam
	 */
	public static List<String> str2List(String str) {
		return str2List(str, null);
	}

	/**
	 * 将字符串转换为List，根据给定分隔符 例如：用逗号分隔，"str1,str2,str3..."=>[str1,str2,str3...]
	 *
	 * @param str
	 * @param separator
	 * @return
	 * @date 2016年9月5日
	 * @author lam
	 */
	public static List<String> str2List(String str, String separator) {
		if (isBlank(str)) {
			return Collections.emptyList();
		}
		if (separator == null) {
			separator = ",";
		}
		String[] strs = str.split(separator);
		return Arrays.asList(strs);
	}

	/**
	 * 分隔字段
	 * 
	 * @param fields
	 * @return
	 * @date 2016年12月30日
	 * @author lam
	 */
	public static String[][] splitFields(String[] fields) {
		String[] fssTmp = null;
		String[] fds = new String[fields.length];
		String[] keys = new String[fields.length];
		for (int i = 0; i < fields.length; i++) {
			if (fields[i].indexOf("=>") != -1 && (fssTmp = fields[i].split("=>")).length > 1) {
				fds[i] = fssTmp[0];
				keys[i] = fssTmp[1];
			} else {
				fds[i] = fields[i];
				keys[i] = fields[i];
			}
		}
		return new String[][] { fds, keys };
	}
	
	/**
	 * 判断是否有中文字符
	 * @param str
	 * @return
	 */
	public static boolean isContainChinese(String str) {
		if (isBlank(str)) {
			return false;
		}
		for (char c : str.toCharArray()) {
			if (c >= 0x4E00 && c <= 0x9FA5) {
				return true;
			}
		}
		return false;
	}
	
	public static List<String> matcher(String s, String regex) {
		   List<String> strs = new ArrayList<>();
		   Pattern p = Pattern.compile(regex);
		   Matcher m = p.matcher(s);
		   while(m.find()) {
		     strs.add(m.group());
		   }
		   return strs;
		}

	/**
	 * 验证签名是否一直
	 * 
	 * @param str
	 * @param key
	 * @param sign
	 * @return
	 */
	public static boolean checkSign(String str, String key, String sign) {
		String signTmp = sign(str, key);
		boolean flag = equals(signTmp, sign);
		if (!flag) {
			logger.error("checkSign:{}, sign:{}", signTmp, sign);
		}
		return flag;
	}

	/**
	 * 签名
	 * 
	 * @param str
	 * @param key
	 * @return
	 */
	public static String sign(String str, String key) {
		return Md5Util.md5Encrypt(str + key);
	}

}